package com.phonetools.commonutils.security

import java.security.PrivateKey
import java.security.PublicKey
import java.security.Signature

/**
 * 数字签名
 * MD5withRSA/SHA1withRSA/SHA256withRSA
 */

/*fun main{
    val publicKeyStr =
            "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDymOuE7z9SfGv3Czq1ZAwzukNknR1iVTBZurJ6BTh9cBiQUczZ9U4HgBtgIWMRaLNeFjkFMszQz/uDmWQXMJbcsYuSAEJNxUn5KuHAp2YEWfV2CXTj/3I/Q9rhGVq+aLs0rgfCvVXoxFjJV+uGPtzXxhVZTahCcwUo20MSPqI0WwIDAQAB"
        val privateKeyStr =
            "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAPKY64TvP1J8a/cLOrVkDDO6Q2SdHWJVMFm6snoFOH1wGJBRzNn1TgeAG2AhYxFos14WOQUyzNDP+4OZZBcwltyxi5IAQk3FSfkq4cCnZgRZ9XYJdOP/cj9D2uEZWr5ouzSuB8K9VejEWMlX64Y+3NfGFVlNqEJzBSjbQxI+ojRbAgMBAAECgYAT4bpzk5Px86Z5gZ8XHJLvblV1mna9B1RGFknoPCNMDHLG6R1Lw5HYhYQ41aOj2pvQmyujJG2qs1DekSSlzeKfHMgoiHiKO/LPLCe4QgbkCsxtTy+SloVM/EirMBCwoPjMwYPqoxVm1a38kCqNgiitMpGooTXflCR0jgGvR9ej+QJBAPwTrCkk6SupWERxQG7yBdCIO9lyWzer9DPa2+JmMcoNydov4bq2ZUCgpum8JkAkmhonM1Oz8x6OFOwcbzHnyZ0CQQD2X3qpvF1Iyc3M/gqZcOSTORQTRkZVSt5ctPnJw6lIGax+HMr9YNccuiwlfi2UtSA0NOtC5yozDS8s9Xt2yHBXAkAzfKkrdjiSDHLU9/TbNF/vqgPfdDYhduPYO5mx8oG07YAPKryGcH7Z5nZxQ1bkvxUixmL7c8Pyt76aQ2yK2vcZAkBLoDFR6t0jm7aNhymPwiSXwHyWEgtC4TFyeab3NRVAaYkWSRZSQqilS8yDUcECFbsl61yP889zTke94Die1JYPAkEAjy3tzsbUeVCMF5CTfAklXSoJbJMZiWvW0S5lolAV9TOVmXFsW+itONAivg7k6HYkxGQF78u6JdcCf5y5p1DqSQ=="

        val signContent = "数字签名"
        val signBase64 = signContent.md5SignBase64(privateKeyStr)
        val signArray = signContent.toByteArray().md5Sign(privateKeyStr.genRSAPrivateKey())
        val result1 = signContent.md5Verify(publicKeyStr, signArray.base64Encode())
        val result2 = signContent.toByteArray().md5Verify(publicKeyStr.genRSAPublicKey(), signArray)
        Log.d(TAG, "sign: $signBase64")
        Log.d(TAG, "signHex: ${signArray.toHex()}")
        Log.d(TAG, "verify1= $result1 | verify2= $result2")
}*/

private fun sign(mode: String, privateKey: PrivateKey, content: ByteArray): ByteArray {
    //获取数字签名实例对象
    val signature = Signature.getInstance(mode)
    //初始化签名
    signature.initSign(privateKey)
    //设置数据源
    signature.update(content)
    //签名
    return signature.sign()
}

private fun verify(
    mode: String, publicKey: PublicKey,
    content: ByteArray, sign: ByteArray
): Boolean {
    val signature = Signature.getInstance(mode)
    //初始化签名
    signature.initVerify(publicKey)
    //传入数据源
    signature.update(content)
    //校验签名信息
    return signature.verify(sign)
}

/**
 * MD5签名，
 * @param privateKey 私钥
 * @return ByteArray
 * */
fun md5Sign(input: ByteArray, privateKey: PrivateKey): ByteArray =
    sign("MD5withRSA", privateKey, input)

/**
 * MD5验证
 * @param publicKey 公钥
 * @param sign 签名
 * @return Boolean
 * */
fun md5Verify(input: ByteArray, publicKey: PublicKey, sign: ByteArray): Boolean =
    verify("MD5withRSA", publicKey, input, sign)

/**
 * MD5签名，输出Base64
 * @param privateKeyBase64 私钥 in Base54 格式
 * @return String
 * */
fun md5SignBase64(input: String, privateKeyBase64: String): String =
    base64Encode(md5Sign(input.toByteArray(), genRSAPrivateKey(base64Decode(privateKeyBase64))))

/**
 * MD5验证
 * @param publicKeyBase64 公钥 in Base54 格式
 * @param signBase64 签名 in Base54 格式
 * @return Boolean
 * */
fun md5Verify(input: String, publicKeyBase64: String, signBase64: String): Boolean =
    md5Verify(
        input.toByteArray(),
        genRSAPublicKey(base64Decode(publicKeyBase64)),
        base64Decode(signBase64)
    )

/**
 * SHA1签名
 * @param privateKey 私钥
 * @return ByteArray
 * */
fun sha1Sign(input: ByteArray, privateKey: PrivateKey): ByteArray {
    return sign("SHA1withRSA", privateKey, input)
}

/**
 * SHA1验证
 * @param publicKey 公钥
 * @param sign 签名
 * @return Boolean
 * */
fun sha1Verify(input: ByteArray, publicKey: PublicKey, sign: ByteArray): Boolean {
    return verify("SHA1withRSA", publicKey, input, sign)
}

/**
 * SHA1签名，输出Base64
 * @param privateKeyBase64 私钥 in Base64 格式
 * @return String
 * */
fun sha1SignBase64(input: String, privateKeyBase64: String): String =
    base64Encode(sha1Sign(input.toByteArray(), genRSAPrivateKey(base64Decode(privateKeyBase64))))

/**
 * SHA1验证
 * @param publicKeyBase64 公钥 in Base54 格式
 * @param signBase64 签名 in Base54 格式
 * @return Boolean
 * */
fun sha1Verify(input: String, publicKeyBase64: String, signBase64: String): Boolean =
    sha1Verify(
        input.toByteArray(),
        genRSAPublicKey(base64Decode(publicKeyBase64)),
        base64Decode(signBase64)
    )

/**
 * SHA256签名，输出ByteArray
 * @param privateKey 私钥
 * @return ByteArray
 * */
fun sha256Sign(input: ByteArray, privateKey: PrivateKey): ByteArray {
    return sign("SHA256withRSA", privateKey, input)
}

/**
 * SHA256验证
 * @param publicKey 公钥
 * @param sign 签名
 * @return Boolean
 * */
fun sha256Verify(input: ByteArray, publicKey: PublicKey, sign: ByteArray): Boolean {
    return verify("SHA256withRSA", publicKey, input, sign)
}

/**
 * SHA256签名，输出Base64
 * @param privateKeyBase64 私钥 in Base54 格式
 * @return String
 * */
fun sha256SignBase64(input: String, privateKeyBase64: String): String =
    base64Encode(sha256Sign(input.toByteArray(), genRSAPrivateKey(base64Decode(privateKeyBase64))))

/**
 * SHA256验证
 * @param publicKeyBase64 公钥 in Base54 格式
 * @param signBase64 签名 in Base54 格式
 * @return Boolean
 * */
fun sha256Verify(input: String, publicKeyBase64: String, signBase64: String): Boolean =
    sha256Verify(
        input.toByteArray(),
        genRSAPublicKey(base64Decode(publicKeyBase64)),
        base64Decode(signBase64)
    )